import typing
import sys

sys.path.append("../")  # noqa
from collections import defaultdict
from datetime import datetime, timedelta
from typing import Optional, List
import re

from bson import ObjectId
from pymongo import MongoClient, UpdateOne

from config import settings
from task_utils.util_mapping import query_year


client = MongoClient(settings.dsn)

col_inst = client["kexie"]["institution"]
activity_col = client["kexie"]["activity"]
institution_col = client["kexie"]["institution"]
col_register = client["kexie"]["activity_register"]
col_person = client["kexie"]["alumni"]

org_list = [ObjectId("62b945cd9aebef53937fecc0"),
            ObjectId("62b945cd9aebef53937fecc1"),
            ObjectId("62b945cd9aebef53937fecc2"),
            ObjectId("62b945cd9aebef53937fecc4"),
            ObjectId("62b945cd9aebef53937fecc5"),
            ObjectId("62b945cd9aebef53937fecc6"),
            ObjectId("62b945cd9aebef53937fecc7"),
            ObjectId("62b945cd9aebef53937fecc8"),
            ObjectId("62b945cd9aebef53937fecc9"),
            ObjectId("62b945cd9aebef53937fecca"),
            ObjectId("62b945cd9aebef53937feccb")]


def get_series_activity_name(activity_data):
    series_activity_id_dict = defaultdict(list)
    compile_list = [re.compile(x) for x in [r"\d{4}[年]*", r'[第]*[123456789一二三四五六七八九十]+期',
                                            r"[第]*[123456789一二三四五六七八九十]+届",
                                            r"[第]*[123456789一二三四五六七八九十]+次"]]
    split_list = ["-", "：", "--", "——"]
    for item in activity_data:
        s = item["name"]

        res = re.search(r"^['['].*?]", s)
        if res:
            s = res.group()[1:-1]
        for r in compile_list:
            s = re.sub(r, "", s)
        for sp in split_list:
            if sp in s:
                s = s.split(sp)[0]

        series_activity_id_dict[s].append(item["_id"])

    return series_activity_id_dict


def get_series_by_name(s):
    compile_list = [re.compile(x) for x in [r"\d{4}[年]*", r'[第]*[123456789一二三四五六七八九十]+期',
                                            r"[第]*[123456789一二三四五六七八九十]+届",
                                            r"[第]*[123456789一二三四五六七八九十]+次"]]
    split_list = ["-", "：", "--", "——"]
    res = re.search(r"^['['].*?]", s)
    if res:
        s = res.group()[1:-1]
    for r in compile_list:
        s = re.sub(r, "", s)
    for sp in split_list:
        if sp in s:
            s = s.split(sp)[0]
    return s


def update_m_activity_span(year_range):
    activity_data = activity_col.find(year_range, {"name": 1, "institution_id": 1, "co_inst_ids": 1, "end_time": 1})
    activity_data = list(activity_data)
    activity_year_dict = {item["_id"]: item["end_time"].year for item in activity_data}

    org_series_activity_id_dict = {}
    #
    for org in org_list:
        org_activity_data = activity_col.find({"$or": [{"institution_id": org}, {"co_inst_ids": org}], **year_range},
                                              {"name": 1})
        org_activity_data = list(org_activity_data)
        series_activity_id_dict = get_series_activity_name(org_activity_data)
        org_series_activity_id_dict[org] = series_activity_id_dict

    org_result = {}
    for org in org_list:
        org_result[org] = []
        activity_data = activity_col.find({"$or": [{"institution_id": org}, {"co_inst_ids": org}], **year_range},
                                          {"name": 1, "institution_id": 1, "co_inst_ids": 1, "end_time": 1})

        year_activity_dict = defaultdict(list)
        for item in activity_data:
            year_activity_dict[item["end_time"].year].append(
                {"activity_id": item["_id"], "activity_name": get_series_by_name(item["name"])})

        for k, v in year_activity_dict.items():
            temp = defaultdict(int)
            temp["year"] = int(k)
            temp["total"] = len(v)
            for item in v:
                activities = org_series_activity_id_dict[org][item["activity_name"]]
                year = list(set([int(activity_year_dict[x]) for x in activities]))
                year.sort()
                if year:
                    if year.index(int(k)) + 1 == 1:
                        temp["duration_1yr"] += 1
                    elif year.index(int(k)) + 1 == 2:
                        temp["duration_2yr"] += 1
                    elif year.index(int(k)) + 1 == 3:
                        temp["duration_3yr"] += 1
                    elif year.index(int(k)) + 1 == 4:
                        temp["duration_4yr"] += 1
                    elif year.index(int(k)) + 1 == 5:
                        temp["duration_5yr"] += 1
            org_result[org].append(temp)
    update_list = []
    for k, v in org_result.items():
        # update_list.append(UpdateOne({"_id": k}, {"$set": {"m_activity_span": v}}))
        update_list.append(UpdateOne({"_id": k}, {"$addToSet": {"m_activity_span": {"$each": v}}}))
    institution_col.bulk_write(update_list)


def task_update_activity_span(start_year: int = None, end_year: int = None):
    """
    对于该机构组织的所有活动，进行如下处理：
    第一步，去掉活动名称前面的 “xxxx年”、“xxxx”“第n期”、“n期”、“第m届”、“m届”（其中,xxxx为年份数字、n和m为数字或者中文数字“一到九百九十九”）
    第二步，去掉以上内容后，去掉活动名称中“-”、“：”、“--”、“——”之后的部分。
    第三步，如果去掉以上内容后，活动名称剩余部分相同，视为同一个系统活动（也称业务）。
    进而
    (a)累计数出不同“系列活动”的数量，作为环形图分母
    (b)以下逻辑为该 “系列活动” 持续的年份差值数
    对于该机构组织的同一个系列活动，最晚的活动结束日期 和活动开始日期 之间  “对应年份” 相减的差值
    (c)求出各持续年份差值数，分别有多少个“系统活动”
    持续1年的
    持续2年的
    持续3年的
    持续4年的
    持续5年的
    """
    _query_year = {"end_time": query_year(start_year, end_year)}
    update_m_activity_span(_query_year)


if __name__ == '__main__':
    task_update_activity_span(start_year=2022)
    task_update_activity_span(start_year=2023)
